import React, { Component } from 'react';
import {
  View,
  Text,
  TouchableOpacity,
} from 'react-native';
import PropTypes from 'prop-types';

const SegmentedButton = ({
  children, // text to display
  selected = false,
  onPress = () => {},
  first = false,
  last = false,
  borderWidth = 1,
  borerRadius = 6,
  selectedBackgroundColor = '#108eeb',
  unSelectedBackgroundColor = '#fff',
  selectedTextColor = '#fff',
  unSelectedTextColor = '#108eeb',
  activeOpacity = 0.8,
  wrapperStyle,
  textStyle,
}) => {
  return (
    <TouchableOpacity
      activeOpacity={activeOpacity}
      style={[
        {
          flex: 1,
          justifyContent: 'center',
          alignItems: 'center',
          backgroundColor: selected ? selectedBackgroundColor : unSelectedBackgroundColor,
          paddingVertical: 5,
          paddingHorizontal: 12,
        },
        !(first || last) && {
          borderLeftWidth: borderWidth,
          borderRightWidth: borderWidth,
          borderColor: selectedBackgroundColor,
          marginLeft: -1,
        },
        first && {
          borderTopLeftRadius: borerRadius,
          borderBottomLeftRadius: borerRadius,
        },
        last && {
          borderTopRightRadius: borerRadius,
          borderBottomRightRadius: borerRadius,
        },
        wrapperStyle,
      ]}
      onPress={onPress}>
      <Text
        style={[
          {
            color: selected ? selectedTextColor : unSelectedTextColor,
            fontSize: 14,
          },
          textStyle,
        ]}>
        {children}
      </Text>
    </TouchableOpacity>
  );
};

class SegmentedControl extends Component {
  constructor(props) {
    super(props);
    this.state = {
      selectedIndex: [...props.selectedIndex],
    };
  }

  _handleOnPress = (index, callback) => {
    const {
      multiple,
    } = this.props;
    const {
      selectedIndex,
    } = this.state;
    let newIndex = [];
    if (multiple) {
      // when set multiple, must consider that user click the same button twice then the button will recover the same
      // if selectedIndex contains the index, then delete it otherwise add it
      if (selectedIndex.includes(index)) {
        selectedIndex.forEach((v, i) => {
          if (v !== index) {
            newIndex.push(v);
          }
        });
      } else {
        newIndex = [...selectedIndex, index];
      }
      this.setState({ selectedIndex: newIndex }, callback);
    } else {
      newIndex = [index];
      this.setState({ selectedIndex: newIndex }, callback);
    }
    this.props.onChange && this.props.onChange(newIndex);
  };

  /**
   * @selectedIndex {number} index that is selected
   */
  _renderButtons = () => {
    const {
      callbacks,
      names,
      borderRadius,
      wrapperStyle,
      textStyle,
      selectedBackgroundColor,
      unSelectedBackgroundColor,
      selectedTextColor,
      unSelectedTextColor,
      activeOpacity,
    } = this.props;
    const {
      selectedIndex,
    } = this.state;

    const buttonProps = {
      borderRadius,
      textStyle,
      wrapperStyle,
      selectedBackgroundColor,
      unSelectedBackgroundColor,
      selectedTextColor,
      unSelectedTextColor,
      activeOpacity,
    };

    return names.map((v, i) => {
      return (
        <SegmentedButton
          key={i}
          first={i === 0}
          last={i === names.length - 1}
          selected={selectedIndex.includes(i)}
          onPress={() => this._handleOnPress(i, callbacks[i])}
          {...buttonProps}>
          {v}
        </SegmentedButton>
      );
    });
  };

  render() {
    const {
      borderRadius,
      selectedBackgroundColor,
    } = this.props;
    return (
      <View
        style={{
          flexDirection: 'row',
          backgroundColor: '#fff',
          borderRadius: borderRadius + 1,
          borderWidth: 1,
          borderColor: selectedBackgroundColor,
        }}>
        {this._renderButtons()}
      </View>
    );
  }
}

SegmentedControl.propTypes = {
  callbacks: PropTypes.arrayOf(PropTypes.func),
  names: PropTypes.arrayOf(PropTypes.string),
  selectedIndex: PropTypes.arrayOf(PropTypes.number),
  borderRadius: PropTypes.number,
  wrapperStyle: PropTypes.object,
  textStyle: PropTypes.object,
  selectedBackgroundColor: PropTypes.string,
  unSelectedBackgroundColor: PropTypes.string,
  selectedTextColor: PropTypes.string,
  unSelectedTextColor: PropTypes.string,
  activeOpacity: PropTypes.number,
  multiple: PropTypes.bool,
};
SegmentedControl.defaultProps = {
  callbacks: [],
  names: [],
  selectedIndex: [0],
  borderRadius: 6,
  wrapperStyle: {},
  textStyle: {},
  selectedBackgroundColor: '#108eeb',
  unSelectedBackgroundColor: '#fff',
  selectedTextColor: '#fff',
  unSelectedTextColor: '#108eeb',
  activeOpacity: 0.8,
  multiple: false,
};

export default SegmentedControl;
